using Holoville.HOTween;
using Holoville.HOTween.Core;
using Holoville.HOTween.Plugins;
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;

namespace BMCommon
{
    public static class GameObjectExt2
    {


        //private static T GetPropValue<T>(object target, string name)
        //{
        //	FieldInfo field = target.GetType().GetField(name);
        //	if (field != null)
        //	{
        //		return (T)field.GetValue(target);
        //	}
        //	PropertyInfo property = target.GetType().GetProperty(name);
        //	if (property != null)
        //	{
        //		return (T)property.GetValue(target, null);
        //	}
        //	return default(T);
        //}


        public static Color GetPropValue(object target, string name)
        {

            if (target is tk2dBaseSprite)
            {
                return ((tk2dBaseSprite)target).color;
            }

            if (target is tk2dTextMesh)
            {
                return ((tk2dTextMesh)target).color;
            }

            if (target is Material)
            {
                return ((Material)target).color;
            }

            return Color.white;
        }

        private static void SetPropValue(object target, string name, Color val)
        {
            if (target is tk2dBaseSprite)
            {
                ((tk2dBaseSprite)target).color = val;
            }

            if (target is tk2dTextMesh)
            {
                ((tk2dTextMesh)target).color = val;
            }

            if (target is Material)
            {
                ((Material)target).color = val;
            }


            //  target.GetType().GetField(name)?.SetValue(target, val);
            //	target.GetType().GetProperty(name)?.SetValue(target, val, null);
        }

        private static object FindColoredObject(GameObject go)
        {
            if (go.GetComponent<Renderer>() == null)
            {
                return null;
            }
            if (go.GetComponent<Renderer>().sharedMaterial == null)
            {
                return null;
            }
            tk2dBaseSprite component = go.GetComponent<tk2dBaseSprite>();
            if (component != null)
            {
                return component;
            }
            tk2dTextMesh component2 = go.GetComponent<tk2dTextMesh>();
            if (component2 != null)
            {
                return component2;
            }
            if (go.GetComponent<Renderer>().sharedMaterial.HasProperty("_Color"))
            {
                return go.GetComponent<Renderer>().material;
            }
            UnityEngine.Debug.LogError("FindColoredObject Fail : " + go.name);
            return null;
        }

        public static Tweener Round(this GameObject go, int count, float dur, bool clockwise = true)
        {
            HOTween.Complete(go.transform);
            float z = (!clockwise) ? (360f * (float)count) : (-360f * (float)count);
            TweenParms tweenParms = new TweenParms().Prop("localRotation", new PlugQuaternion(new Vector3(0f, 0f, z), EaseType.Linear, false).Beyond360());
            if (dur < 0f)
            {
                tweenParms.Loops((int)dur);
                dur = 0f - dur;
            }
            return HOTween.To(go.transform, dur, tweenParms);
        }

        public static Tweener RoundX(this GameObject go, float angle, float dur, bool clockwise = true)
        {
            HOTween.Complete(go.transform);
            TweenParms tweenParms = new TweenParms().Prop("localRotation", new PlugQuaternion(new Vector3(angle, 0f, 0f), EaseType.Linear, true).Beyond360());
            if (dur < 0f)
            {
                tweenParms.Loops((int)dur);
                dur = 0f - dur;
            }
            return HOTween.To(go.transform, dur, tweenParms);
        }

        public static Tweener RoundY(this GameObject go, float angle, float dur, bool clockwise = true)
        {
            HOTween.Complete(go.transform);
            TweenParms tweenParms = new TweenParms().Prop("localRotation", new PlugQuaternion(new Vector3(0f, angle, 0f), EaseType.Linear, true).Beyond360());
            if (dur < 0f)
            {
                tweenParms.Loops((int)dur);
                dur = 0f - dur;
            }
            return HOTween.To(go.transform, dur, tweenParms);
        }

        public static Tweener ShakeRot(this GameObject go, float dur, float angle)
        {
            HOTween.Complete(go.transform);
            TweenParms p_parms = new TweenParms().Prop("localRotation", new PlugQuaternion(new Vector3(0f, 0f, angle), false)).Ease(EaseType.EaseOutElastic, 0.1f, 0.15f);
            return HOTween.From(go.transform, dur, p_parms);
        }

        public static Tweener Shake(this GameObject go, float dur, Vector2 offset)
        {
            HOTween.Complete(go.transform);
            TweenParms p_parms = new TweenParms().Prop("localPosition", new Vector3(offset.x, offset.y, 0f), true).Ease(EaseType.EaseOutElastic, 0.1f, 0.15f);
            return HOTween.From(go.transform, dur, p_parms);
        }

        public static Tweener Rotate(this GameObject go, float eulerZ, float dur)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localRotation", new Vector3(0f, 0f, eulerZ), true));
        }

        public static Tweener RotateY(this GameObject go, float eulerY, float dur)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localRotation", new Vector3(0f, eulerY, 0f), true));
        }

        public static void PopRotate(this GameObject go)
        {
            HOTween.Complete(go.name);
            Vector3 localScale = go.transform.localScale;
            Sequence sequence = new Sequence(new SequenceParms().Id(go.name));
            sequence.Append(HOTween.To(go.transform, 0.2f, "localScale", localScale * 1.2f));
            sequence.Append(go.Round(1, 1f));
            sequence.Insert(1.3f, HOTween.To(go.transform, 0.2f, "localScale", localScale));
            sequence.Play();
        }

        public static Tweener FadeIn(this GameObject go, float duration = 0.5f, float targetAlpha = 1f, TweenDelegate.TweenCallback onComplete = null)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Complete(obj);
                Color propValue = GetPropValue(obj, "color");
                propValue.a = 0f;
                SetPropValue(obj, "color", propValue);
                propValue.a = targetAlpha;
                TweenParms tweenParms = new TweenParms().Prop("color", propValue).OnStart(Activate, go);
                if (onComplete != null)
                {
                    tweenParms.OnComplete(onComplete);
                }
                return HOTween.To(obj, duration, tweenParms);
            }
            UnityEngine.Debug.LogWarning("GameObject [" + go.name + "] Has no color property");
            return null;
        }

        public static Tweener ChangeColor(this GameObject go, float duration, Color targetColor, TweenDelegate.TweenCallback onComplete = null)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Complete(obj);
                TweenParms tweenParms = new TweenParms().Prop("color", targetColor);
                if (onComplete != null)
                {
                    tweenParms.OnComplete(onComplete);
                }
                return HOTween.To(obj, duration, tweenParms);
            }
            UnityEngine.Debug.LogWarning("GameObject [" + go.name + "] Has no color property");
            return null;
        }

        public static Sequence FadeInRecursively(this GameObject go, float duration = 0.5f, float targetAlpha = 1f, TweenDelegate.TweenCallback onComplete = null)
        {
            HOTween.Complete(go.name);
            SequenceParms sequenceParms = new SequenceParms().Id(go.name);
            if (onComplete != null)
            {
                sequenceParms.OnComplete(onComplete);
            }
            Sequence sequence = new Sequence(sequenceParms);
            sequence.Insert(0f, go.FadeIn(duration, targetAlpha));
            Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>();
            Renderer[] array = componentsInChildren;
            foreach (Renderer renderer in array)
            {
                sequence.Insert(0f, renderer.gameObject.FadeIn(duration, targetAlpha));
            }
            sequence.Play();
            return sequence;
        }

        public static Tweener FadeOut(this GameObject go, float duration = 0.5f, bool deActivate = false, TweenDelegate.TweenCallback onComplete = null)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Complete(obj);
                Color propValue = Color.white;//GetPropValue<Color>(obj, "color");
                propValue.a = 0f;
                TweenParms p_parms = new TweenParms().Prop("color", propValue).OnComplete(Deactivate, go, deActivate, onComplete);
                return HOTween.To(obj, duration, p_parms);
            }
            UnityEngine.Debug.LogWarning("GameObject [" + go.name + "] Has no color property");
            return null;
        }

        public static Sequence FadeOutRecursively(this GameObject go, float duration = 0.5f, bool deActivate = false, TweenDelegate.TweenCallback onComplete = null)
        {
            HOTween.Complete(go.name);
            SequenceParms sequenceParms = new SequenceParms().Id(go.name);
            sequenceParms.OnComplete(Deactivate, go, deActivate, onComplete);
            Sequence sequence = new Sequence(sequenceParms);
            sequence.Insert(0f, go.FadeOut(duration, deActivate));
            Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>();
            Renderer[] array = componentsInChildren;
            foreach (Renderer renderer in array)
            {
                sequence.Insert(0f, renderer.gameObject.FadeOut(duration, deActivate));
            }
            sequence.Play();
            return sequence;
        }

        public static Tweener Popup(this GameObject go, float dur)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localScale", new Vector3(1f, 1f, 1f)).Ease(EaseType.EaseOutBack).OnStart(Activate, go));
        }

        public static Tweener Popout(this GameObject go, float dur, bool autoDestruct)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localScale", new Vector3(0f, 0f, 0f)).Ease(EaseType.EaseInQuad).OnComplete(Deactivate, go, autoDestruct));
        }

        public static Tweener PopupFadeOut(this GameObject go, float dur, bool autoDestruct = false)
        {
            go.FadeOut(dur, autoDestruct);
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localScale", new Vector3(2f, 2f, 2f)));
        }

        public static Tweener PopupFadeIn(this GameObject go, float dur = 1f)
        {
            go.FadeIn(dur);
            HOTween.Complete(go.transform);
            return HOTween.From(go.transform, dur, new TweenParms().Prop("localScale", new Vector3(2f, 2f, 2f)));
        }

        public static Tweener Bounce(this GameObject go, float offsetY, int count, float period = 0.2f, string tweenId = null)
        {
            HOTween.Complete(go.transform);
            Vector3 position = go.transform.position;
            Vector3 vector = position;
            vector.y += offsetY;
            TweenParms tweenParms = new TweenParms().Prop("position", new PlugVector3Path(new Vector3[3]
            {
                position,
                vector,
                position
            }, false)).Ease(EaseType.EaseOutBounce, 10f).Loops(count);
            if (tweenId != null)
            {
                tweenParms.Id(tweenId);
            }
            return HOTween.To(go.transform, period, tweenParms);
        }

        public static Tweener Slide(this GameObject go, Vector3 offset, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("position", offset, true).Ease(ease, easeParam));
        }

        public static Tweener Slide2(this GameObject go, Vector2 offset, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            return go.Slide(new Vector3(offset.x, offset.y, 0f), dur, ease, easeParam);
        }

        public static Tweener SlideLocal(this GameObject go, Vector3 offset, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", offset, true).Ease(ease, easeParam));
        }

        public static Tweener SlideLocal2(this GameObject go, Vector2 offset, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            return go.SlideLocal(new Vector3(offset.x, offset.y, 0f), dur, ease, easeParam);
        }

        public static Tweener SlideLocalAbs(this GameObject go, Vector3 offset, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", offset, false).Ease(ease, easeParam));
        }

        public static Tweener SlideXAbs(this GameObject go, float xPos, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            Vector3 position = go.transform.position;
            position.x = xPos;
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", position, false).Ease(ease, easeParam));
        }

        public static Tweener SlideYAbs(this GameObject go, float yPos, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            Vector3 position = go.transform.position;
            position.y = yPos;
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", position, false).Ease(ease, easeParam));
        }

        public static Tweener SlideX(this GameObject go, float xPos, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", new Vector3(xPos, 0f, 0f), true).Ease(ease, easeParam));
        }

        public static Tweener SlideY(this GameObject go, float yPos, float dur, EaseType ease = EaseType.EaseOutQuad, float easeParam = 1.7f)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", new Vector3(0f, yPos, 0f), true).Ease(ease, easeParam));
        }

        public static Tweener SlideXYElastic(this GameObject go, float xPos, float yPos, float dur, float amplitude, float period)
        {
            HOTween.Complete(go.transform);
            return HOTween.To(go.transform, dur, new TweenParms().Prop("localPosition", new Vector3(xPos, yPos, 0f), true).Ease(EaseType.EaseOutElastic, amplitude, period));
        }

        public static Tweener Blink(this GameObject go, float freq)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Kill(obj);
                if (freq < 0f)
                {
                    return null;
                }
                Color propValue = GetPropValue(obj, "color");
                propValue.a = 0f;
                SetPropValue(obj, "color", propValue);
                propValue.a = 1f;
                float p_duration = 1f / (freq * 2f);
                TweenParms p_parms = new TweenParms().Prop("color", propValue).Loops(-1, LoopType.Yoyo).OnStart(Activate, go);
                return HOTween.To(obj, p_duration, p_parms);
            }
            UnityEngine.Debug.LogWarning("GameObject [" + go.name + "] Has no color property");
            return null;
        }

        public static Tweener Blink2(this GameObject go, int count, float period = 0.6f, float alphaMax = 1f)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Kill(obj);
                Color propValue = GetPropValue(obj, "color");
                propValue.a = 0f;
                SetPropValue(obj, "color", propValue);
                propValue.a = alphaMax;
                period *= 0.5f;
                TweenParms p_parms = new TweenParms().Prop("color", propValue).Loops(count * 2, LoopType.Yoyo).OnStart(Activate, go);
                return HOTween.To(obj, period, p_parms);
            }
            UnityEngine.Debug.LogWarning("GameObject [" + go.name + "] Has no color property");
            return null;
        }

        public static bool StopBlink(this GameObject go)
        {
            object obj = FindColoredObject(go);
            if (obj != null)
            {
                HOTween.Kill(obj);
                SetPropValue(obj, "color", Color.white);
                return true;
            }
            return false;
        }

        public static void Activate(TweenEvent data)
        {
            GameObject gameObject = data.parms[0] as GameObject;
            if (!(gameObject == null))
            {
                if (gameObject.GetComponent<Renderer>() != null)
                {
                    gameObject.GetComponent<Renderer>().enabled = true;
                }
                if (!gameObject.activeSelf)
                {
                    gameObject.SetActive(true);
                }
            }
        }

        public static void Deactivate(TweenEvent data)
        {
            GameObject gameObject = data.parms[0] as GameObject;
            if (!(gameObject == null))
            {
                if ((bool)data.parms[1])
                {
                    gameObject.SetActive(false);
                }
                else if (gameObject.GetComponent<Renderer>() != null)
                {
                    gameObject.GetComponent<Renderer>().enabled = false;
                }
                else
                {
                    UnityEngine.Debug.LogWarning("Deactivate On Empty gameObejct");
                }
                if (data.parms.Length >= 3)
                {
                    (data.parms[2] as TweenDelegate.TweenCallback)?.Invoke();
                }
            }
        }

        public static void PositionFromBottom(this GameObject go, float pixelOffset)
        {
            Vector3 localPosition = go.transform.localPosition;
            float num = 0f;
            if (go.GetComponent<Renderer>() != null)
            {
                Vector3 extents = go.GetComponent<Renderer>().bounds.extents;
                num = extents.y;
            }
            float num2 = Camera.main.orthographicSize / (float)Screen.height * 2f;
            localPosition.y = 0f - Camera.main.orthographicSize + num + pixelOffset * num2;
            go.transform.localPosition = localPosition;
        }
    }
}